# import os
#
# from docx import Document
# from docx import Document
# from docx.shared import Inches,Pt
# from docx.oxml import OxmlElement
# from docx.oxml.ns import qn
# from lxml import etree
# import io
# import shutil
# import re
# from docx import Document
# from docx.shared import RGBColor
# from lxml import etree
# from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
# from docx.enum.text import WD_UNDERLINE
# import requests
# import json_repair
# import json
#
# #调用大模型
# def dify_chat(query):
#     # global pool_sema
#     # # 开启线程限制
#     # with pool_sema:
#     url = 'http://192.168.43.12:8083/v1/chat-messages'  # v1/chat-messages'调用聊天框  workflows/run智能体
#     api_key = 'app-E5OKzE323dg4s4g8T8lwmG40'  # 'app-ldimOhba65Dq5BlHpPXQaDka'  # 替换为您的实际API密钥
#
#     # 请求头
#     headers = {
#         'Authorization': f'Bearer {api_key}',
#         'Content-Type': 'application/json'
#     }
#
#     # 请求数据
#     data = {
#         "inputs": {},
#         "query": query,
#         "response_mode": "streaming",  # blocking streaming
#         "conversation_id": "",
#         "user": "abc-123",
#     }
#
#     # 将数据转换为JSON字符串
#     data_json = json.dumps(data)
#
#     answer = ''
#
#     # 发送GET请求，并设置stream=True
#     with requests.post(url, headers=headers, data=data_json.encode("utf-8"), stream=True) as r:
#         # 检查请求是否成功
#         r.raise_for_status()
#
#         # 打印每一行文本
#         for line in r.iter_lines():
#
#             # 忽略保持连接的空行
#             if line:
#                 # 解码每一行，因为返回的数据可能是字节串
#                 line = line.decode('utf-8')
#                 if 'data: ' in line:
#                     data = json.loads(line.replace('data: ', ''))
#                     if data['event'] == 'message':
#                         # print(data['answer'])
#                         answer += data['answer']
#                         print(data['answer'],end='')
#                     elif data['event'] == 'message_end':
#                         break
#
#     #去除思考过程
#     answer = answer.split('</think>')[-1]
#
#     return answer
#
# #获取大模型json结果
# def json_process(data_answ):
#     pattern = r'```json(.*?)```'
#     matches = re.findall(pattern, data_answ, re.DOTALL)  # 抽取出内容并判断长度
#     if matches:
#         c_statement = json_repair.loads(matches[-1])
#         # print("\n-------step2查到的对应的内容为：\n", c_statement)
#     else:
#         c_statement = {}
#     # decoded_object = json_repair.loads(c_statement)
#     # return json.dumps(decoded_object,ensure_ascii=False)
#     return c_statement
#
# def copy_element_style(doc):
#     if element.tag.endswith('p'):  # 段落
#
#         #段落文本
#         para_text = ''
#         judge = False
#
#         para = {'para': {}, 'runs': [], 'pad': False, "pad_num": 0}
#
#         for run in element_xml.xpath('.//w:r', namespaces=namespaces):
#             mid = {}
#             # 提取run中的文本
#             run_text = "".join(run.xpath('.//w:t/text()', namespaces=namespaces))
#
#             #给大模型的文本，如果有下划线且为空，则将空置换为_
#             llm_text = run_text
#             print(f"文本：\t{[run_text]}")
#
#
#             # new_doc.add_paragraph(run_text)
#             # r = p.add_run(run_text)
#
        #     # 提取并应用字体样式
        #     print("提取并应用字体样式:", run.xpath('.//w:rPr/w:rFonts/@w:ascii', namespaces=namespaces))
        #     if run.xpath('.//w:rPr/w:rFonts/@w:ascii', namespaces=namespaces):
        #         # r.font.name = run.xpath('.//w:rPr/w:rFonts/@w:ascii', namespaces=namespaces)[0]
        #         # r._element.rPr.rFonts.set(qn('w:eastAsia'), r.font.name)
        #         aaa = run.xpath('.//w:rPr/w:rFonts/@w:ascii', namespaces=namespaces)[0]
        #         #字体样式
        #         mid['font_name'] = run.xpath('.//w:rPr/w:rFonts/@w:ascii', namespaces=namespaces)[0]
        #     else:
        #         #默认为宋体
        #         mid['font_name'] = '宋体'
        #
        #     # 提取并应用字体大小
        #     size = run.xpath('.//w:rPr/w:sz/@w:val', namespaces=namespaces)
        #     if size:
        #         # r.font.size = Pt(int(size[0]) / 2)  # docx中的大小单位是磅，而XML中通常是半点
        #         mid['font_size'] = Pt(int(size[0]) / 2)  # docx中的大小单位是磅，而XML中通常是半点
        #
        #     # 提取并应用字体颜色
        #     color = run.xpath('.//w:rPr/w:color/@w:val', namespaces=namespaces)
        #     if color:
        #         print("color:",color) #color=["auto"]
        #         if color[0].lower() == "auto":
        #             # 处理 "auto" 颜色值，例如使用默认颜色或指定一个颜色
        #             # 这里我们使用黑色作为示例
        #             # r.font.color.rgb = RGBColor(0, 0, 0)  # 黑色的RGB值
        #             font_color = RGBColor(0, 0, 0)  # 黑色的RGB值
        #         else:
        #             # r.font.color.rgb = RGBColor.from_string(color[0])
        #             font_color = RGBColor.from_string(color[0])
        #         mid['font_color'] = font_color
        #         # # 提取并应用加粗样式 因为有些文本有的加粗有的不加粗 这里先暂时不弄
        #     # bold = run.xpath('.//w:rPr/w:b', namespaces=namespaces)
        #     # if bold:
        #     #     r.font.bold = True
        #     # 检查是否有下划线属性
        #     underline = run.xpath('.//w:rPr/w:u/@w:val', namespaces=namespaces)
        #     # print(underline)
        #     # 如果存在下划线属性，获取其值，否则默认为None
        #     underline_val = underline[0] if underline and underline[0]!="none" else None
        #     # print("underline_val:",underline_val)
        #     # 如果underline_val不为None，则设置下划线
        #     if underline_val is not None and str(underline_val) is not "none":
        #         # 在docx中，underline可以是True、False或者下划线类型的字符串
        #         # 例如 'single', 'double', 'thick', 'dotted' 等
        #         # 这里将underline_val直接作为参数传递，假设它是一个有效的下划线类型
        #         underline_enum = getattr(WD_UNDERLINE, underline_val.upper(), None)
        #         # r.underline = underline_enum
        #         # r_underline = r.underline
        #         mid['underline'] = underline_enum
        #         para['pad'] = True
        #         print("r.underline",[run_text,underline_enum])
        #     # for pic in run.xpath('.//w:drawing', namespaces=namespaces):
        #     #     # pic是包含图片信息的XML元素
        #     #     # 获取图片的RID
        #     #     blip = pic.xpath('.//a:blip', namespaces=namespaces)
        #     #     if blip:
        #     #         # 假设blip是一个列表，通常情况下只有一个元素
        #     #         blipRID = blip[0].attrib.get(qn('r:embed'))
        #     #         # 这里可以处理blipRID，例如打印或者进行其他操作
        #     #
        #     #         # 添加图片到新文档
        #     #         rel = doc.part.rels[blipRID]
        #     #         image_part = doc.part.related_parts[blipRID].blob  # bytes
        #     #         image_stream = io.BytesIO(image_part)
        #     #         new_doc.add_picture(image_stream, width=Inches(1.25))
        #
        #     # # 给大模型的文本，如果有下划线且为空，则将空置换为_
        #     if (not llm_text or set(llm_text) == set(' ')) and 'underline' in mid.keys():
        #         if llm_text:
        #             llm_text = llm_text.replace(' ','_')
        #         else:
        #             llm_text = '_'
        #     para_text += llm_text
        #     mid['text'] = llm_text
        #
        #     #如果为需填充下划线，判断是否要和前面拼到一起
        #     if 'underline' in mid.keys():
        #         #如果为第一个，则直接添加
        #         if len(para['runs']) > 0:
        #             if 'underline' in para['runs'][-1].keys():
        #                 para['runs'][-1]['text'] += llm_text
        #             else:
        #                 para['runs'].append(mid)
        #                 para['pad_num'] += 1
        #         else:
        #             para['runs'].append(mid)
        #             para['pad_num'] += 1
        #     else:
        #         para['runs'].append(mid)
        #
        # para['para']['text'] = para_text
        # # print('段落文本：', [para_text])
        # # if judge:
        # #     print('需要填充的文本：', [para_text])
        # return para

    # elif element.tag.endswith('tbl'):  # 表格
    #     # 提取表格内容
    #     list_d = [i for i in doc.element.body.inner_content_elements if "<w:tbl>" in str(i)]
    #     # print(list_d)
    #     table = doc.tables[list_d.index(element)]
    #
    #     new_table = new_doc.add_table(rows=len(table.rows), cols=len(table.columns))
    #     new_table.style = 'Table Grid'
    #     try:
    #         # 遍历原始表格的每一行和单元格
    #         for row_idx, row in enumerate(table.rows):
    #             for col_idx, cell in enumerate(row.cells):
    #                 # 将单元格文本添加到新表格的相应单元格
    #                 new_table.cell(row_idx, col_idx).text = cell.text.strip()
    #     except Exception as e:
    #         # 如果发生索引错误，打印错误信息并跳过当前行
    #         print(f"Error: {e} encountered while processing row ")
#
# def copy_docx(source_path, target_path):
#     # 加载源文档
#     source_doc = Document(source_path)
#     # 创建目标文档
#     target_doc = Document()
#
#     # 遍历源文档中的所有段落
#     # for paragraph in source_doc.paragraphs:
#     #     copy_paragraph_from_doc_to_doc(paragraph, target_doc)
#     paras = []
#     for element in source_doc.element.body:
#         paras.append(copy_element_style(element,source_doc,target_doc))
#
#     #遍历paras，去除掉空的部分
#     paras = [para for para in paras if para]
#
#     # 给大模型的文本
#     llm_input_list = []
#     pad_num = 0
#
#     #遍历给大模型
#     for i, para in enumerate(paras):
#
#         mid_para = re.sub(r'[^\w\s]', '', para['para']['text'])
#
#         #如果全为空，先向前找文本
#         if set(' ') == set(mid_para) and para['pad']:
#             for past_para in paras[:i][::-1]:
#                 mid_past_para = re.sub(r'[^\w\s]', '', past_para['para']['text'])
#                 if set(' ') != set(mid_past_para) and mid_past_para:
#                     para['para']['text'] = f"{past_para['para']['text']}\n{para['para']['text']}"
#                     break
#
#
#         if para['pad']:
#             print('=================',[para['para']['text']])
#             llm_input_list.append(para['para']['text'])
#             pad_num += para['pad_num']
#
#     #如果需要大模型填充
#     if llm_input_list:
#         llm_input_text = '\n'.join(llm_input_list)
#         print(llm_input_text)
#         print(pad_num)
#         # result = ["标的2：数字化技术平台2024 年第五批采购项目", "南方电网数字企业科技(广东)有限公司", "2024", "12", "09"]
#         # result = ["南方电网数字企业科技(广东)有限公司", "曹旭", "男", 35, "董事长", "南方电网数字企业科技(广东)有限公司", "南方电网数字企业科技(广东)有限公司", "2024", "12", "09"]
#
#         #调用大模型获取结果
#         #提示词
#         prompt = '''
#         根据输入的信息，格式化文本中下划线位置需要填充的内容，返回格式为列表，以下为参考样例
#         <输入>
#         <文本>
#         标的名称:_____________
#         投标人：_____________________________（盖公章/电子印章）
#         ___年___月___日
#         </文本>
#         <填写数量>
#         5
#         </填写数量>
#         <信息>
#         {"标的名称": "标的1：项目1", "标包名称": "标包2：项目1", "投标人":"国网公司", "时间": "2025-05-02 11:52:33"}
#         </信息>
#         </输入>
#         <输出>
#         ```json
#         ["标的1：项目1", "国网公司", "2025", "05",  "02"]
#         ```
#         </输出>
#         '''
#         basic_info = {"标的名称": "标的2：数字化技术平台2024 年第五批采购项目", "标包名称": "标包1：北斗运营服务应用V3.0（安全升级改造）建设项目", "投标人":"南方电网数字企业科技(广东)有限公司", "时间": "2024-12-09 21:34:52", "法人姓名": "曹旭", "法人性别": "男", "法人年龄": 35, "法人职务": "董事长"}
#         llm_input_text = f'''
#         <文本>
#         {llm_input_text}
#         </文本>
#         <填写数量>
#         {pad_num}
#         </填写数量>
#         <信息>
#         {basic_info}
#         </信息>
#         '''
#         #调用大模型
#         query = f"{prompt}{llm_input_text}"
#         answer = dify_chat(query)
#
#         #将结果转为json
#         result = json_process(answer)
#
#         #填充原文本需要填充的部分
#         for para in paras:
#             if para['pad']:
#                 for run in para['runs']:
#                     if 'underline' in run.keys():
#
#                         run['text'] = f" {result[0]} "
#                         result = result[1:]
#
#         #填充到文档中
#         for para in paras:
#             #添加段落
#             p = target_doc.add_paragraph()
#
#             # 段前段后间距
#             p.paragraph_format.space_before = para['para']['space_before']
#             p.paragraph_format.space_after = para['para']['space_after']
#
#             # 设置首行缩进
#             p.paragraph_format.first_line_indent = para['para']['first_line_indent']
#
#             # 段落对齐方式
#             if 'alignment' in para['para'].keys():
#                 p.alignment = para['para']['alignment']
#
#             #段落内添加文本
#             for run in para['runs']:
#                 r = p.add_run(run['text'])
#
#                 #文本格式化
#                 #字体
#                 if 'font_name' in run.keys():
#                     r.font.name = run['font_name']
#                     r._element.rPr.rFonts.set(qn('w:eastAsia'), r.font.name)
#
#                 # 字号
#                 if 'font_size' in run.keys():
#                     r.font.size = run['font_size']  # docx中的大小单位是磅，而XML中通常是半点
#
#                 # 字体颜色
#                 if 'font_color' in run.keys():
#                     r.font.color.rgb = run['font_color']
#
#                 #下划线
#                 if 'underline' in run.keys():
#                     r.underline = run['underline']
#
#     # 保存目标文档
#     target_doc.save(target_path)
#
# # 使用函数
# # source_file ='./test/sample.docx'
# # target_file =  './general_docx/output.docx'
# # copy_docx(source_file, target_file)
# # source_file ='./s/'
# source_file ='/media/977GB/wcj_work/禅道/新视图开发/zentao/bid/generate/源文档'
# target_file = './生成文档/'
# if not os.path.isdir(target_file):
#     os.makedirs(target_file)
# source_files=os.listdir(source_file)
# for file in source_files:
#     if file.endswith("docx"):
#         file_name,f_ty=os.path.splitext(file)
#         source_path = os.path.join(source_file, file)
#         target_path=os.path.join(target_file,"testout_put"+file)
#         copy_docx(source_path, target_path)
# #可以提取到所有内容 问题 第一个样式获取文本 后面那个样式获取图片及其表格
#
# #如果现有表格数据会导致表格的位置在后面 位置错误了
# #第一个样式中读取表格及其图片数据
# #有个问题 下划线没实现 读取不到下划线

from docx import Document

doc = Document('/media/977GB/wcj_work/禅道/新视图开发/zentao/bid/文档/商务文件模板/1_商务_封面.docx')

llm_text = []
pad_num = 0

# 遍历所有段落
for paragraph in doc.paragraphs:

    pad_judge = False
    para_text = ''
    runs = []
    # 遍历段落内的所有Run
    for run in paragraph.runs:
        run_text = run.text
        # 检查Run是否应用了下划线样式
        if run.font.underline and (not run_text or set(run_text) == set(' ')):
            # 替换该Run的文本内容（保留原有下划线样式）
            # run.text = "要填充的新内容"
            if run_text:
                run_text = run_text.replace(' ', '_')
            else:
                run_text = '_'
            pad_judge = True

            #判断是否需要合并
            # 如果为第一个，则直接添加
            if len(runs) > 0:
                if runs[-1] != 'underline':
                    pad_num += 1
            else:
                pad_num += 1

            runs.append('underline')

        else:
            runs.append('')

        para_text += run_text

    if pad_judge:
        llm_text.append(para_text)

# print(pad_num)
# print('\n'.join(llm_text))

result = ['标的1:投标人投标人投标人投标人投标人', '投标人投标人投标人投标人投标人投标人投标人投标人', '2020', '5', '10']
# 遍历所有段落
for paragraph in doc.paragraphs:

    pad_judge = False
    para_text = ''
    runs = []
    # 遍历段落内的所有Run
    for run in paragraph.runs:
        run_text = run.text
        # 检查Run是否应用了下划线样式
        if run.font.underline and (not run_text or set(run_text) == set(' ')):
            # 替换该Run的文本内容（保留原有下划线样式）
            #判断是否需要合并
            # 如果为第一个，则直接添加
            if len(runs) > 0:
                if runs[-1] != 'underline':
                    run.text = result[0]
                    result = result[1:]
            else:
                run.text = result[0]
                result = result[1:]

            runs.append('underline')
        else:
            runs.append('')

doc.save('结果.docx')